<?php
/**
 * Groo_Driver:: defines an API for implementing storage backends for Groo.
 *
 * $Horde: groo/lib/Driver.php,v 1.25.2.9 2006/03/03 23:00:29 chuck Exp $
 *
 * Copyright 2001-2006 Horde Project (http://www.horde.org/)
 *
 * See the enclosed file LICENSE for license information (ASL). If you
 * did not receive this file, see http://www.horde.org/licenses/asl.php.
 *
 * @author  Jon Parise <jon@horde.org>
 * @since   Groo 1.0
 * @package Groo
 */
class Groo_Driver {

    /**
     * Array holding the current item list.  Each array entry is a hash
     * describing a item.  The array is indexed numerically by item ID.
     *
     * @var array
     */
    var $_items = array();

    /**
     * String containing the current collection name.
     *
     * @var string
     */
    var $_collection = '';

    /**
     * Lists items based on the given criteria. All items will be
     * returned by default.
     *
     * @return array    Returns a list of the requested items.
     */
    function listItems()
    {
        return $this->_items;
    }

    /**
     * Generate a universal / unique identifier for a task. This is
     * NOT something that we expect to be able to parse into a
     * tasklist and a taskId.
     *
     * @return string  A nice unique string (should be 255 chars or less).
     */
    function generateUID()
    {
        return date('YmdHis') . '.' .
            substr(base_convert(microtime(), 10, 36), -16) .
            '@' . $GLOBALS['conf']['server']['name'];
    }

    /**
     * Attempts to return a concrete Groo_Driver instance based on $driver.
     *
     * @param string    $collection    The name of the current collection.
     *
     * @param string    $driver     The type of concrete Groo_Driver subclass
     *                              to return.  The is based on the storage
     *                              driver ($driver).  The code is dynamically
     *                              included.
     *
     * @param array     $params     (optional) A hash containing any additional
     *                              configuration or connection parameters a
     *                              subclass might need.
     *
     * @return mixed    The newly created concrete Groo_Driver instance, or
     *                  false on an error.
     */
    function &factory($collection = '', $driver = null, $params = null)
    {
        if (is_null($driver)) {
            $driver = $GLOBALS['conf']['storage']['driver'];
        }

        $driver = basename($driver);

        if (is_null($params)) {
            $params = Horde::getDriverConfig('storage', $driver);
        }

        require_once dirname(__FILE__) . '/Driver/' . $driver . '.php';
        $class = 'Groo_Driver_' . $driver;
        if (class_exists($class)) {
            $groo = &new $class($collection, $params);
        } else {
            $groo = false;
        }

        return $groo;
    }

    /**
     * Attempts to return a reference to a concrete Groo_Driver instance based
     * on $driver.
     *
     * It will only create a new instance if no Groo_Driver instance with the
     * same parameters currently exists.
     *
     * This should be used if multiple storage sources are required.
     *
     * This method must be invoked as: $var = &Groo_Driver::singleton()
     *
     * @param string    $collection    The name of the current collection.
     *
     * @param string    $driver     The type of concrete Groo_Driver subclass
     *                              to return.  The is based on the storage
     *                              driver ($driver).  The code is dynamically
     *                              included.
     *
     * @param array     $params     (optional) A hash containing any additional
     *                              configuration or connection parameters a
     *                              subclass might need.
     *
     * @return mixed    The created concrete Groo_Driver instance, or false
     *                  on error.
     */
    function &singleton($collection = '', $driver = null, $params = null)
    {
        static $instances;

        if (is_null($driver)) {
            $driver = $GLOBALS['conf']['storage']['driver'];
        }

        if (is_null($params)) {
            $params = Horde::getDriverConfig('storage', $driver);
        }

        if (!isset($instances)) {
            $instances = array();
        }

        $signature = serialize(array($collection, $driver, $params));
        if (!isset($instances[$signature])) {
            $instances[$signature] = &Groo_Driver::factory($collection, $driver, $params);
        }

        return $instances[$signature];
    }

}
